#include "clcomfuncs.h"
#include <string.h>
#include <iostream>
#include <fstream>
#include <qglobal.h>
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    #include <QTextCodec>
#else
    #include <QtCore5Compat/QTextCodec>
#endif
#include <QDir>
#include <QCoreApplication>
#include <stdarg.h>

struct Spliters
{
    int position;
    int size;
    Spliters()
    {
        position = -1;
        size = 0;
    }
};

bool compare_vp(Spliters sa, Spliters sb)
{
    return sa.position < sb.position;
}

_tagJasonValue& _tagJasonValue::operator=(_tagJasonValue& other)
{
    this->_type = other._type;

    vector<string>::iterator it = other._valueVec.begin();
    for (; it != other._valueVec.end(); ++it)
    {
        this->_valueVec.push_back(*it);
    }

    return *this;
}
_tagARGNode::_tagARGNode()
{
    this->aType = E_ARG_TYPE_NO;
    this->pValue = NULL;
}
_tagARGNode& _tagARGNode::operator = (const _tagARGNode& other)
{
    this->aType = other.aType;
    this->pValue = other.pValue;

    return *this;
}

CLComFuncs::CLComFuncs(void)
{
}

CLComFuncs::~CLComFuncs(void)
{
}
qint64 CLComFuncs::min(qint64 a, qint64 b)
{
    return a > b?b:a;
}
qint64 CLComFuncs::max(qint64 a, qint64 b)
{
    return a < b?b:a;
}
// 判断是否为数字，如果是并转化成double
bool CLComFuncs::IsNumber_f(const char* sourceStr, double& outDouble)
{
    qint64 size = strlen(sourceStr);

    if (0 == size)
    {
        return false;
    }

    for (int i = 0; i<size; ++i)
    {
        if ('.' == sourceStr[i])
        {
            continue;
        }
        if ('0' > sourceStr[i] || '9' < sourceStr[i])
        {
            return false;
        }
    }

    outDouble = atof(sourceStr);
    return true;
}

// 判断字符串是不是数字，如果是数字则转成数字,如果是浮点数，则截取整数位
bool CLComFuncs::IsNumber_i(const char* sourceStr, qint64& outNumberInt)
{
    qint64 size = strlen(sourceStr);

    if (0 == size)
    {
        return false;
    }

    for (int i = 0; i<size; ++i)
    {
        if ('.' == sourceStr[i] || (0 == i && '-' == sourceStr[i]))
        {
            continue;
        }
        if ('0' > sourceStr[i] || '9' < sourceStr[i])
        {
            return false;
        }
    }

    outNumberInt = 0;
    int nega = 1;
    int cur = 0;
    if (sourceStr[0] == '-')
    {
        nega = -1;
        cur = 1;
    }

    for (int i = cur; i<size; ++i)
    {
        outNumberInt = outNumberInt * 10 + sourceStr[cur] - '0';
    }

    outNumberInt = outNumberInt * nega;
    return true;
}

// 判断字符串是否数字，如果是数字则转成字符串，如果没达到minlen长度，则前面加0
bool CLComFuncs::Num2String(char* outString, int& outLen, qint64 inNumber, int minLen)
{
    if (NULL == outString)
    {
        printf("没有为输出字符串分配空间！");
        return false;
    }

    char value[100];
    memset(value, 0, 100);
    outLen = 0;
    if (0 > inNumber)
    {
        value[outLen++] = '-';
    }

    while (true)
    {
        value[outLen++] = char(inNumber % 10 + '0');
        inNumber = inNumber / 10;
        if (0 == inNumber)
        {
            break;
        }
    }

    value[outLen] = '\0';

    string tempstr = value;
    ReverseString(tempstr);
    strcpy(value, tempstr.c_str());

    for (int i = 0; i<minLen; ++i, ++outLen)
    {
        outString[i] = '\0';
        if (outLen >= minLen)
        {
            break;
        }
        outString[i] = '0';
        outString[i + 1] = 0;
    }
    strcat(outString, value);
    return true;
}

// 删除字符串ousrcestr中所有的delstr
bool CLComFuncs::DelSubStr(char* sourceStr, const char* delStr)
{
    const int size_source = (int)strlen(sourceStr);
    const int size_delstr = (int)strlen(delStr);

    char* temp = new char[size_source];

    if (0 == size_source || 0 == size_delstr)
    {
        return false;
    }

    int tempLen = 0;

    for (int i = 0; i<size_source;)
    {
        if (delStr[0] == sourceStr[i])
        {
            for (int j = 0; j<size_delstr; ++j)
            {
                if (delStr[j] == sourceStr[i + j] && (j + 1) == size_delstr)
                {
                    i += size_delstr;
                    break;
                }
                if (delStr[j] != sourceStr[i + j])
                {
                    temp[tempLen++] = sourceStr[i++];
                    break;
                }
            }
        }
        else
        {
            temp[tempLen++] = sourceStr[i++];
        }
    }

    //strcpy(sourceStr, temp);
    memset(sourceStr, 0, size_source);
    strcpy(sourceStr, temp);

    return true;
}

// 将sourcestr中的oldstr替换为newstr
bool CLComFuncs::ReplaceSubstr(string& sourceStr, const string& oldStr, const string& newStr)
{
    int size_source = (int)sourceStr.size();
    int size_old = (int)oldStr.size();
    //int size_new = (int)newStr.size();

    if (0 == size_source || 0 == size_old)
    {
        printf("有空串");
        return false;
    }
    if (size_source < size_old)
    {
        printf("不合逻辑");
        return false;
    }
    size_t start = 0;
    while (1)
    {
        size_t spp = sourceStr.find(oldStr, start);

        if (spp == string::npos || spp > sourceStr.size())
            break;

        sourceStr.erase(spp, size_old);
        sourceStr.insert(spp, newStr);

        start = spp + oldStr.size() + 1;
    }
    return true;
}

// 字符串如果有大写字母则全转小写
bool CLComFuncs::LowerCaseString(string& strInput)
{
    if (0 == strInput.size())
    {
        printf("空串");
        return false;
    }

    for (unsigned int i = 0; i< strInput.size(); ++i)
    {
        if (IsChinese(strInput[i]))
        {
            ++i;
        }
        else
        {
            if ('A' <= strInput[i] && 'Z' >= strInput[i])
            {
                strInput[i] = strInput[i] + 32;
            }
        }
    }
    return true;
}

// 判断是否为中文
bool CLComFuncs::IsChinese(char inChar)
{
    char mask = (char)128; /* MASK=10000000 */

    if ((inChar&mask) == mask){  /* Chinese */
        return true;
    }
    else{              /* ASCII */
        return false;
    }
}

bool CLComFuncs::CapCaseString(string& strInput)
{
    if (0 == strInput.size())
    {
        printf("空串");
        return false;
    }
    for (unsigned int i = 0; i< strInput.size(); ++i)
    {
        if (IsChinese(strInput[i]))
        {
            ++i;
        }
        else
        {
            if ('a' <= strInput[i] && 'z' >= strInput[i])
            {
                strInput[i] = strInput[i] - 32;
            }
        }
    }
    return true;
}

// 查找ssrouce中的sfind，intstart为其实查找地址， forward为真则正向查找，false为反向查找， 返回值为-1为没找到
qint64 CLComFuncs::FindMix(const string& sSource, const string& sfind, qint64 intStart, bool forward)
{
    if (0 == sfind.size() || 0 == sSource.size())
    {
        return -1;
    }
    if (0 > intStart || (qint64)sSource.size() < intStart)
    {
        printf("ERROR start position!");
        return -1;
    }

    if (forward)
    {
        for (size_t i = intStart; i < sSource.size();)
        {
            if (sSource[i] == sfind[0])
            {
                for (unsigned int j = 0; j<sfind.size(); ++j)
                {
                    if (sSource[i + j] == sfind[j])
                    {
                        if ((j + 1) == sfind.size())
                        {
                            return i;
                        }
                        continue;
                    }
                    else
                    {
                        (IsChinese(sSource[i])) ? (i += 2) : ++i;
                        break;
                    }
                }
            }
            else
            {
                (IsChinese(sSource[i])) ? (i += 2) : ++i;
            }
        }
    }
    else   //反向查找
    {
        for (qint64 i = intStart; i >= 0; --i)
        {
            if (sSource[i] == sfind[sfind.size() - 1])
            {
                for (qint64 j = (qint64)sfind.size() - 1, k = 0; (j >= 0) && (0 <= (i - k)); --j, ++k)
                {
                    if (sSource[i - k] == sfind[j])
                    {
                        if (0 == j)
                        {
                            return (i - k);
                        }
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
    }

    return -1;
}

// 删除strsource中从strstart到strend之间的字符串，知道end位置，如果isclear为真则删除所有的，如果为false则删除第一个, 如果strstart为空，则删除从头到strend的字符串，如果strend为空，则删除strstart字符串
//返回值判断是否删除过
bool CLComFuncs::ClearString(string& strSource, const string& strStart, const string& strEnd, bool isClearAll, int end)
{
    qint64 indexStart = -1;
    qint64 indexEnd = -1;
    qint64 startFind = 0;
    bool isFirst = true;

    if (0 == strSource.size())
    {
        return false;
    }

    if (0 == strStart.size() && 0 == strEnd.size())
    {
        return false;
    }

    do
    {
        if (0 == strEnd.size())
        {
            indexStart = FindMix(strSource, strStart, startFind, true);
            if (-1 == indexStart || (-1 != end && indexStart > end))
            {
                break;
            }
            strSource.erase(indexStart, strStart.size());
            isFirst = false;
            continue;
        }
        else if (0 == strStart.size())
        {
            indexStart = 0;
            indexEnd = FindMix(strSource, strEnd, startFind, true);
            if (-1 == indexEnd)
            {
                break;
            }

            indexEnd = indexEnd + strEnd.size();
            if (-1 != end && indexEnd > end)
            {
                break;
            }
            strSource.erase(indexStart, indexEnd - indexStart);
            isFirst = false;
            continue;
        }
        else
        {
            indexEnd = FindMix(strSource, strEnd, startFind, true);

            if (-1 == indexEnd)
            {
                break;
            }

            indexEnd = indexEnd + strEnd.size();
            if (-1 != end && indexEnd > end)
            {
                break;
            }


            indexStart = FindMix(strSource, strStart, indexEnd - strEnd.size(), false);
            if (-1 == indexStart)
            {
                startFind = indexEnd + strEnd.size();
                continue;
            }
            else
            {
                isFirst = false;
                strSource.erase(indexStart, indexEnd - indexStart);
            }
        }
    } while (isClearAll);

    if (isFirst)
    {
        return false;
    }
    else
    {
        return true;
    }
}

// 从source中截取size个字节，如果source的长度不够则不截取，该函数为了截取中文字符的，防止将中文字符分开
bool CLComFuncs::TruncateString(string& strSource, int size)
{
    int length = 0;
    if (strSource.size() <= (unsigned int)size)
    {
        return false;
    }
    else
    {
        while (length < size)
        {
            if (IsChinese(strSource[length]))
            {
                if ((length + 2) > size)
                {
                    break;
                }
                length += 2;
            }
            else
            {
                ++length;
            }
        }

        strSource.erase(length);
    }
    return true;
}

// 判断是否是全角数字
bool CLComFuncs::IsSBCCase(char cur1, char cur2)
{
    int there = cur1;
    int behind = cur2;

    if (-93 == there)
    {
        if ((-31 <= behind && -6 >= behind) || (-63 <= behind && -38 >= behind) || (-80 <= behind && -71 >= behind))
        {
            return true;
        }
    }
    return false;
}

// 是否为字符
bool CLComFuncs::IsLetter(char ch)
{
    if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
    {
        return true;
    }
    return false;
}
bool CLComFuncs::IsNumber(char ch)
{
    if (ch >= '0' && ch <= '9')
    {
        return true;
    }
    return false;
}

size_t CLComFuncs::FilterString(string& source, string beSplited, string spliter, qint64 start, bool forward)
{
    if (start >= (qint64)source.size() || start < 0 || 0 == (qint64)spliter.size() || 0 == (qint64)beSplited.size() || 0 == (qint64)source.size())
    {
        return start;
    }
    vector<string>* vp = new vector<string>;
    vector<string>::iterator it;
    SplitString(vp, spliter, beSplited, false);

    bool flag = false;
    qint64 index = start;
    if (forward)
    {
        for (qint64 i = start; i<(qint64)source.size();)
        {
            for (it = vp->begin(); it != vp->end(); ++it)
            {
                for (size_t j = 0; 0 != (*it)[j];)
                {
                    if ((*it)[j] == source[i + j])
                    {
                        ++j;
                        if (0 == (*it)[j])
                        {
                            i = i + j;
                            index = i;
                            flag = true;
                            break;
                        }

                    }
                    else
                    {
                        break;
                    }
                }
            }
            if (!flag)
            {
                break;
            }
            else
            {
                flag = false;
            }
        }
    }
    else
    {
        for (qint64 i = start; 0 <= i;)
        {
            for (it = vp->begin(); it != vp->end(); ++it)
            {
                for (qint64 j = (*it).size() - 1, k = 0; 0 <= j; --j, ++k)
                {
                    if ((*it)[j] == source[i - k])
                    {
                        if (0 == j)
                        {
                            index = i - k;
                            i = index - 1;
                            flag = true;
                            break;
                        }

                    }
                    else
                    {
                        break;
                    }
                }
            }
            if (!flag)
            {
                break;
            }
            else
            {
                flag = false;
            }
        }
    }

    if (index == start && !forward)
    {
        ++index;
    }
    delete vp;
    vp = NULL;
    return index;
}

void CLComFuncs::SplitString(vector<string>* vp, string spliter, string& source, bool fillNull)
{
    vector<string> v_spliters;
    vector<string>::iterator it;

    vector<Spliters> v_position;
    vector<Spliters>::iterator it_int;

    if (NULL == vp || 0 == spliter.size() || 0 == source.size())
    {
        return;
    }

    if ("," != spliter && string::npos != spliter.find(","))
    {
        SplitString(&v_spliters, ",", spliter, false);
    }
    else if (spliter.size() > source.size())
    {
        vp->push_back(source);
        return;
    }
    else
    {
        v_spliters.push_back(spliter);
    }

    qint64 k = 0;

    for (it = v_spliters.begin(); it != v_spliters.end();)
    {
        //k = source.find_first_of(*it, k);
        k = FindMix(source, *it, k, true);
        //k = source.find_first_of(*it, k);
        if (-1 != k)
        {
            Spliters sp;
            sp.position = (int)k;
            sp.size = (int)(*it).size();

            v_position.push_back(sp);
            k += (*it).size();
        }
        else
        {
            ++it;
            k = 0;
        }
    }

    sort(v_position.begin(), v_position.end(), compare_vp);


    k = 0;
    int start = 0;
    for (it_int = v_position.begin(); it_int != v_position.end(); ++it_int)
    {
        string temp = source.substr(start, (*it_int).position - start);

        if ("" != temp || fillNull)
        {
            vp->push_back(temp);
        }
        start = (*it_int).position + (*it_int).size;
    }


    if (start < (int)source.size())
    {
        vp->push_back(source.substr(start, source.size() - start));
    }
}
void CLComFuncs::ExtractString(vector<string>* vp, string startspliter, string endspliter, string& source)
{
    qint64 startIndex = 0;
    qint64 endIndex = 0;
    while (true)
    {
        startIndex = FindMix(source, startspliter, endIndex, true);
        if (startIndex == -1)
        {
            break;
        }
        endIndex = FindMix(source, endspliter, startIndex + 1, true);
        if (endIndex == -1)
        {
            break;
        }
        vp->push_back(source.substr(startIndex+1, endIndex - startIndex - 1));
    }
}

float CLComFuncs::SimilarString(string& str1, string& str2)
{
    if ("" == str1 || "" == str2)
    {
        return 0;
    }

    int countSameChar = 0;
    float percent = 0;
    string longStr = "";
    string shortStr = "";
    string tempSTR = "";
    qint64 index = 0;
    qint64 lastIndex = 0;

    if (str1.size() > str2.size())
    {
        longStr = str1;
        shortStr = str2;
    }
    else
    {
        longStr = str2;
        shortStr = str1;
    }

    for (unsigned int i = 0; i < shortStr.size(); ++i)
    {
        if (IsChinese(shortStr[i]))
        {
            tempSTR = shortStr.substr(i, 2);;
            index = FindMix(longStr, tempSTR, lastIndex, true);
            ++i;
            if (-1 == index)
            {
                continue;
            }
            else
            {
                lastIndex = (index + 2);
                countSameChar += 2;
            }
        }
        else
        {
            tempSTR = shortStr.substr(i, 1);;
            index = FindMix(longStr, tempSTR, lastIndex, true);
            if (-1 == index)
            {
                continue;
            }
            else
            {
                lastIndex = (index + 1);
                ++countSameChar;
            }

        }
    }
    percent = (float)countSameChar / longStr.size();

    return percent;

}
void CLComFuncs::ExtractByWords(const string& fileName, const string& words, const string& outFileName)
{
    ifstream fin(fileName.c_str());
    ofstream fout(outFileName.c_str());

    string strRW = "";

    if (!fin.is_open() || !fout.is_open())
    {
        cout << "FILE ERROR!" << endl;
        return;
    }

    while (getline(fin, strRW, '\n'))
    {
        if (string::npos != strRW.find(words))
        {
            fout << strRW << endl;
            //fout << "\n" << endl;
        }
    }

    fin.close();
    fout.close();
}
bool CLComFuncs::ConvertWidthToHalf(string& str)
{
    char chars[2];
    //tep = 0;

    for (qint64 i = 0; i<(qint64)str.size();)
    {
        qint16 v = (qint16)str[i];
        if ((0 <= v && 127 >= v))
        {
            ++i;
            continue;
        }

        //65281~65374
        //33~126
        chars[0] = str[i];
        chars[1] = str[i + 1];

        if (-95 == chars[0] && -95 == chars[1])
        {
            str[i] = chars[1] + 127;
            str.erase(i + 1, 1);
            ++i;
        }

        if (-93 == chars[0] && -95 <= chars[1] && -2 >= chars[1])
        {
            str[i] = chars[1] + 128;
            str.erase(i + 1, 1);
            ++i;
        }
        else
        {
            i += 2;
        }
    }

    return true;
}
bool CLComFuncs::ConvertHalfToWidth(string& str)
{
    //tep = 0;

    for (qint64 i = 0; i<(qint64)str.size();)
    {
        qint16 v = (qint16)str[i];
        if ((0 > v || 127 < v))
        {
            i += 2;
            continue;
        }
        if (32 > str[i])
        {
            ++i;
            continue;
        }

        if (32 == str[i])
        {
            str[i] = -95;
            str.insert(i, 1, -95);
            i += 2;
            continue;
        }

        //65281~65374
        //33~126
        if (33 <= str[i] && 126 >= str[i])
        {
            str.insert(i, 1, -93);
            ++i;
            str[i] = str[i] - 128;
            ++i;
        }
    }

    return true;
}
bool CLComFuncs::ConvertHalfToWidth(string& str, vector<int>& v_exceptChars)
{
    //tep = 0;
    vector<int>::iterator it;
    bool flag = false;

    for (unsigned int i = 0; i<str.size();)
    {
        flag = false;
        qint16 v = (qint16)str[i];
        if ((0 > v || 127 < v))
        {
            i += 2;
            continue;
        }
        for (it = v_exceptChars.begin(); it != v_exceptChars.end(); ++it)
        {
            if (str[i] == *it)
            {
                ++i;
                flag = true;
                break;
            }
        }
        if (flag)
        {
            continue;
        }

        if (32 > str[i])
        {
            ++i;
            continue;
        }

        if (32 == str[i])
        {
            str[i] = -95;
            str.insert(i, 1, -95);
            i += 2;
            continue;
        }

        //65281~65374
        //33~126
        if (33 <= str[i] && 126 >= str[i])
        {
            str.insert(i, 1, -93);
            ++i;
            str[i] = str[i] - 128;
            ++i;
        }
    }

    return true;
}

void CLComFuncs::GetNumber(string inputstr, char splitec, qint64* outputNumber)
{
    *outputNumber = 0;
    size_t index = inputstr.find(splitec);
    if (string::npos != index)
    {
        IsNumber_i(inputstr.substr(index + 1).c_str(), *outputNumber);
    }
}
void CLComFuncs::GetNumber(string inputstr, char splitec, int* outputNumber)
{
    *outputNumber = 0;
    size_t index = inputstr.find(splitec);
    if (string::npos != index)
    {
        qint64 i = 0;
        IsNumber_i(inputstr.substr(index + 1).c_str(), i);
        *outputNumber = (int)i;
    }
}
void CLComFuncs::GetString(string inputstr, char splitec, string& outputStr)
{
    outputStr = "";
    size_t index = inputstr.find(splitec);
    if (string::npos != index)
    {
        outputStr = inputstr.substr(index + 1);
    }
}
void CLComFuncs::GetOX(string inputstr, char splitec, bool& outputNumber)
{
    outputNumber = false;
    size_t index = inputstr.find(splitec);
    if (string::npos != index)
    {
        index = atoi(inputstr.substr(index + 1).c_str());
        if (0 < index)
        {
            outputNumber = true;
        }
    }
}

bool CLComFuncs::ReverseString(string& inputstr)
{
    if (inputstr.length() == 0)
    {
        return true;
    }
    char temp;
    size_t start = 0;
    size_t end = inputstr.size() - 1;

    while (start < end)
    {
        temp = inputstr[start];
        inputstr[start] = inputstr[end];
        inputstr[end] = temp;
        ++start;
        --end;
    }
    return true;
    /*
    string tempStr = inputstr;
    int size = inputstr.length();

    inputstr = "";
    for(int i=(size - 1); i>=0; --i)
    {
    inputstr += tempStr[i];
    }
    return true;
    */
}

bool CLComFuncs::Decimal2Hex(qint64 inputNumber, string& outputNumber)
{
    outputNumber = "";

    while (0 != inputNumber)
    {
        int r = inputNumber % 16;
        if (r < 10)
        {
            outputNumber += char(r + '0');
        }
        else
        {
            r = r - 10;
            outputNumber += char(r + 'A');
        }
        inputNumber = inputNumber / 16;
    }
    if (0 != outputNumber.length() % 2)
    {
        outputNumber += "0";
    }

    ReverseString(outputNumber);

    return true;
}

bool CLComFuncs::Hex2Decimal(const string& inputstr, qint64& outputNumber)
{
    size_t size = inputstr.length();

    for (size_t i = 0; i<size; ++i)
    {
        int number = 0;
        if ('9' >= inputstr[i])
        {
            number = inputstr[i] - '0';
        }
        else
        {
            number = 10 + inputstr[i] - 'A';
        }

        if (0 == number)
        {
            continue;
        }

        qint64 tempNumber = 1;
        size_t k = (size - i - 1);

        k <<= 2;
        tempNumber <<= k;

        tempNumber *= number;

        outputNumber += tempNumber;
    }

    return true;
}

char* CLComFuncs::ltrim(char *str)
{
    if (strlen(str) <= 0) return str;

    char *p = str;
    while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') p++;
    strcpy(str,p);
    return str;
}

char* CLComFuncs::rtrim(char *str)
{
    if (strlen(str) <= 0) return str;

    //char *p = &str[strlen(str) - 1];
    qint64 i = -1;
    for (i = (qint64)strlen(str) - 1; i >= 0; i--)
    if (str[i] != ' ' && str[i] != '\t' && str[i] != '\r' && str[i] != '\n') break;
    str[i + 1] = 0;
    return str;
}

char* CLComFuncs::trim(char* in)
{
    return rtrim(ltrim(in));
}

bool CLComFuncs::FloadIsZero(double f)
{
    return f>-0.000001&&f<0.000001;
}
/**
* @brief 多字节转成宽字节\n
* @param[in]      szstr            多字节字符串
* @param[in/out] pwchar           宽字节字符串
* @param[in]      wlen             宽字节字符串最大可用长度
* @return       返回HS_NO_ERROR表示成功，其他错误定义见"comfunlib/com_error.h"
*/
size_t CLComFuncs::multibyte2widechar(
        const char* szstr,
        wchar_t** pwchar)
{
    std::string strLocale = setlocale(LC_ALL, "");
    //const char* chSrc = s.c_str();
    size_t nDestSize = mbstowcs(NULL, szstr, 0) + 1;
    if (nDestSize <= 0)
    {
        return 0;
    }
    *pwchar = new wchar_t[nDestSize+2];
    wmemset(*pwchar, 0, nDestSize+2);
    mbstowcs(*pwchar,szstr,nDestSize);

    setlocale(LC_ALL, strLocale.c_str());
    return nDestSize;
}

/**
* @brief 宽字节转成多字节\n
* @param[in]      pwchar            宽字节字符串
* @param[in/out] szstr             多字节字符串
* @param[in]      szlen             多字节字符串最大可用长度
* @return       返回HS_NO_ERROR表示成功，其他错误定义见"comfunlib/com_error.h"
*/
size_t CLComFuncs::widechar2multibyte(
        const wchar_t* pwchar,
        char** szstr)
{
    std::string strLocale = setlocale(LC_ALL, "");

    size_t nDestSize = wcstombs(NULL, pwchar, 0) + 1;

    if (nDestSize <= 0)
    {
        return 0;
    }
    *szstr = new char[nDestSize+1];
    memset(*szstr,0,nDestSize+1);
    wcstombs(*szstr,pwchar,nDestSize);

    setlocale(LC_ALL, strLocale.c_str());
    return nDestSize;
}

bool CLComFuncs::IsWow64()
{
    if(QSysInfo::currentCpuArchitecture().contains("64"))
    {
        return true;
    }
    return false;
}
bool CLComFuncs::FindFirstFileExists(const char* lpPath, const char* suffix)
{
    // 判断路径是否存在
     QDir dir(lpPath);
     if(!dir.exists())
     {
         return false;
     }
     dir.setFilter(QDir::Files | QDir::NoSymLinks);
     QFileInfoList list = dir.entryInfoList();

     int file_count = list.count();
     if(file_count <= 0)
     {
         return false;
     }

     QStringList string_list;
     for(int i=0; i<file_count; i++)
     {
         QFileInfo file_info = list.at(i);
         QString suffixf = file_info.suffix();

         if(file_info.isDir() && suffixf.length() == 0)
         {
             return true;
         }
         else if (QString::compare(suffixf, suffix, Qt::CaseInsensitive))
         {
            return true;
         }
     }
     return false;
}
bool CLComFuncs::FindAllFile(
        const char* path,
        const char* suffix,
        const char* filenamehavestr,
        vector<string>& vecfiles,
        bool recursion)
{
    // 判断路径是否存在
     QDir dir(path);
     if(!dir.exists())
     {
         return false;
     }
     dir.setFilter(
                 QDir::Files | QDir::Dirs | QDir::NoDot | QDir::NoDotDot | QDir::NoSymLinks);
     QFileInfoList list = dir.entryInfoList();

     int file_count = list.count();
     if(file_count <= 0)
     {
         return false;
     }

     QStringList string_list;
     for(int i=0; i<file_count; i++)
     {
         QFileInfo file_info = list.at(i);
         QString csuffix = file_info.suffix();
         if(file_info.isDir() && recursion)
         {
             return FindAllFile(
                         file_info.path().toLatin1().data(),
                         suffix,
                         filenamehavestr,
                         vecfiles,
                         recursion);
         }
         else
         {
             if (strlen(suffix) > 0)
             {
                if (!csuffix.contains(suffix))
                {
                    continue;
                }
             }
             if (strlen(filenamehavestr) > 0)
             {
                 if (!file_info.fileName().contains(suffix))
                 {
                     continue;
                 }
             }
            vecfiles.push_back(file_info.absoluteFilePath().toLatin1().data());
         }
     }
}
bool CLComFuncs::FilePathExists(const char* lpPath)
{
    QDir dir(lpPath);
    if(!dir.exists())
    {
        return false;
    }
    return true;
}
bool CLComFuncs::FileIsExist(const char* filefullname)
{
    QFileInfo f(filefullname);

    return f.exists();
}
void CLComFuncs::Char2HexString(char* source, size_t size)
{
    char tempchar[10] = { 0 };
    size_t len = size;//strlen(source);
    int count = 0;
    string str = "";;
    for (size_t i = 0; i<len; ++i)
    {
        sprintf(tempchar, "%02x", source[i]);
        size_t templen = strlen(tempchar);
        if (2 < templen)
        {
            str += tempchar[templen - 2];
            str += tempchar[templen - 1];
        }
        else
        {
            str += tempchar;
            ++count;
        }
    }
    strcpy(source, str.c_str());
}
bool CLComFuncs::LogicIP(const char* ipstr)
{
    int countDot = 0;
    char numberstr[20] = { 0 };
    int index = 0;
    if (18 < strlen(ipstr)){
        return false;
    }

    for (int i = 0; ipstr[i] != 0; ++i){
        if ('.' == ipstr[i]){
            if (0 != strlen(numberstr)){
                int j = atoi(numberstr);
                if (255 < j || 0 > j){
                    return false;
                }
                else{
                    memset(numberstr, 0, 20);
                    index = 0;
                }
            }
            ++countDot;
        }
        else{
            numberstr[index++] = ipstr[i];
        }
    }
    if (0 != strlen(numberstr)){
        int j = atoi(numberstr);
        if (255 < j || 0 > j){
            return false;
        }
    }
    if (3 != countDot){
        return false;
    }
    return true;
}
bool CLComFuncs::SetWorkDir2ExeDir()
{
    return QDir::setCurrent(QCoreApplication::applicationDirPath());
}
bool CLComFuncs::GetLocation(string& dir)
{
    dir = QCoreApplication::applicationDirPath().toLatin1().data();
    return true;
}
void CLComFuncs::CodeString(string& source)
{
    if (source.size() == 0){
        return;
    }
    string tempstr = "";
    for (size_t i = 0; i<source.size(); ++i){
        switch (source[i]){
        case '-':
            tempstr += "ox";
            break;
        case '1':
            tempstr += "oe";
            break;
        case '2':
            tempstr += "to";
            break;
        case '3':
            tempstr += "te";
            break;
        case '4':
            tempstr += "fr";
            break;
        case '5':
            tempstr += "fe";
            break;
        case '6':
            tempstr += "sx";
            break;
        case '7':
            tempstr += "sn";
            break;
        case '8':
            tempstr += "et";
            break;
        case '9':
            tempstr += "ne";
            break;
        case '0':
            tempstr += "tn";
            break;
        default:
            break;
        }
    }
    //
    ReverseString(tempstr);
    source = tempstr;
}
void CLComFuncs::DecodeString(string& source)
{
    if (source.size() == 0){
        return;
    }
    string tempstr = "";
    string elementstr = "";
    ReverseString(source);
    for (size_t i = 0; i<source.size(); ++i){
        elementstr += source[i];
        if ("ox" == elementstr){
            tempstr += "-";
            elementstr = "";
        }
        else if ("oe" == elementstr){
            tempstr += "1";
            elementstr = "";
        }
        else if ("to" == elementstr){
            tempstr += "2";
            elementstr = "";
        }
        else if ("te" == elementstr){
            tempstr += "3";
            elementstr = "";
        }
        else if ("fr" == elementstr){
            tempstr += "4";
            elementstr = "";
        }
        else if ("fe" == elementstr){
            tempstr += "5";
            elementstr = "";
        }
        else if ("sx" == elementstr){
            tempstr += "6";
            elementstr = "";
        }
        else if ("sn" == elementstr){
            tempstr += "7";
            elementstr = "";
        }
        else if ("et" == elementstr){
            tempstr += "8";
            elementstr = "";
        }
        else if ("ne" == elementstr){
            tempstr += "9";
            elementstr = "";
        }
        else if ("tn" == elementstr){
            tempstr += "0";
            elementstr = "";
        }
    }
    source = tempstr;
}
bool  CLComFuncs::Make_dir(string path)
{
    int index = FindMix(path, ":\\", 0, true);
    string nowcreatedir = "";

    if (index < 0)
    {
        index = 0;
    }
    else
    {
        index += 2;
    }
    QDir dir;
    while (true)
    {
        size_t Index2 = index;
        index = FindMix(path, "\\", index, true);
        if (-1 == index)
        {
            if (-1 == FindMix(path, ".", Index2, true))
            {
                return dir.mkdir(path.c_str());
            }
            return true;
        }
        nowcreatedir = path.substr(0, ++index);
        dir.mkdir(nowcreatedir.c_str());
    }
    return true;
}
bool CLComFuncs::ParseJason(string srcstr, map<string, _tagJasonValue>& columnmap)
{
    qint64 startIndex = FindMix(srcstr, "{", 0, true);
    qint64 endIndex = FindMix(srcstr, "}", srcstr.size() - 1, false);

    if (-1 != startIndex && -1 != endIndex)
    {
        srcstr = srcstr.substr(startIndex + 1, endIndex - 1);
    }

    while (true)
    {
        startIndex = FindMix(srcstr, "\"", 0, true);//键起始
        if (startIndex == -1)
        {
            break;
        }
        endIndex = FindMix(srcstr, "\"", startIndex + 1, true); //键结束
        if (endIndex == -1)
        {
            break;
        }
        string columnstr = srcstr.substr(startIndex + 1, endIndex - startIndex - 1); //取键
        //string valuestr = "";

        startIndex = FindMix(srcstr, ":", endIndex, true);
        if (startIndex == -1)
        {
            break;
        }
        //值可能有三种情况，一种是数组，一种是单值，还有一种是单值，但是单值是一个结构体
        for (size_t j = startIndex + 1; j<srcstr.size(); ++j)
        {
            if ('\"' == srcstr[j]) //单值且不是结构体
            {
                endIndex = FindMix(srcstr, "\"", j + 1, true);
                if (endIndex == -1)
                {
                    break;
                }
                //valuestr = srcstr.substr(j+1, endIndex-2);
                _tagJasonValue valuejv;
                valuejv._valueVec.push_back(srcstr.substr(j + 1, endIndex - j - 1));
                valuejv._type = 0;
                columnmap.insert(pair<string, _tagJasonValue>(columnstr, valuejv));

                srcstr.erase(0, endIndex + 1);
                break;
            }
            else if ('[' == srcstr[j]) //数组
            {
                endIndex = FindMix(srcstr, "]", j + 1, true);
                if (endIndex == -1)
                {
                    break;
                }
                _tagJasonValue valuejv;

                string tempstr = srcstr.substr(j + 1, endIndex - j - 1);
                ExtractString(&valuejv._valueVec, "{", "}", tempstr);
                valuejv._type = 2;
                columnmap.insert(pair<string, _tagJasonValue>(columnstr, valuejv));

                srcstr.erase(0, endIndex + 1);
                break;
            }
            else if ('{' == srcstr[j]) //单值结构体
            {
                endIndex = FindMix(srcstr, "}", j + 1, true);
                if (endIndex == -1)
                {
                    break;
                }
                _tagJasonValue valuejv;
                valuejv._valueVec.push_back(srcstr.substr(j + 1, endIndex - j));
                valuejv._type = 1;
                columnmap.insert(pair<string, _tagJasonValue>(columnstr, valuejv));

                srcstr.erase(0, endIndex + 1);
                break;
            }
            else if (' ' != srcstr[j])
            {
                endIndex = FindMix(srcstr, ",", j + 1, true);
                if (endIndex == -1)
                {
                    endIndex = srcstr.size();
                }
                //valuestr = srcstr.substr(j+1, endIndex-2);
                _tagJasonValue valuejv;
                valuejv._valueVec.push_back(srcstr.substr(j, endIndex - j));
                valuejv._type = 0;
                columnmap.insert(pair<string, _tagJasonValue>(columnstr, valuejv));

                srcstr.erase(0, endIndex + 1);
                break;
            }
        }
    }
    return true;
}

bool CLComFuncs::Struct2NumString(const char* srcstr, int len, string& outstr)
{
    outstr = "";
    char tempchars[8] = { 0 };
    for (int i = 0; i<len; ++i)
    {
        sprintf(tempchars, "%d", srcstr[i]);
        if (outstr != "")
        {
            outstr += ",";
        }
        outstr += tempchars;
        memset(tempchars, 0, 8);
    }
    return true;
}
bool CLComFuncs::NumString2Struct(string& srcstr, char* outstr, size_t& outlen)
{
    vector<string> vNumbers;
    SplitString(&vNumbers, ",", srcstr, false);
    outlen = vNumbers.size();
    for (size_t i = 0; i<vNumbers.size(); ++i)
    {
        outstr[i] = atoi(vNumbers[i].c_str());
    }

    return true;
}
bool CLComFuncs::FileNameIsLogic(const char* filename)
{
    // 	2 文件名除了开头之外任何地方都可以使用空格。
    // 		3 文件名中不能有下列符号：“？”、“、”、“╲”、“*”、““”、“”“、“<”、“>”、“|”。
    // 		4 Windows 98文件名不区分大小写，但在显示时可以保留大小写格式。
    // 		5 文件名中可以包含多个间隔符，如“我的文件。我的图片。001”。
    string invalidstrings[10] = { "？", "、", "╲", "*", "“", "”", "<", ">", "|", "" };
    string invalidstrings2[10] = { "<", ">", "/", "\\", "|", ":", "\"", "*", "?", "" };
    string tempstr = filename;
    size_t size = tempstr.size();
    if (size > 255)
    {
        return false;
    }
    if (tempstr[0] == ' ')
    {
        return false;
    }

    for (int i = 0; invalidstrings[i] != ""; ++i)
    {
        if (-1 != FindMix(tempstr, invalidstrings[i], 0, true))
        {
            return false;
        }
        if (-1 != FindMix(tempstr, invalidstrings2[i], 0, true))
        {
            return false;
        }
    }
    return true;
}
bool CLComFuncs::CopyFolder(const char* lpszTo, const char* lpszFrom, bool override)//拷贝文件夹
{
    QDir directory(lpszFrom);
    if (!directory.exists())
    {
        return false;
    }

    QString srcPath = QDir::toNativeSeparators(lpszFrom);
    if (!srcPath.endsWith(QDir::separator()))
        srcPath += QDir::separator();
    QString dstPath = QDir::toNativeSeparators(lpszTo);
    if (!dstPath.endsWith(QDir::separator()))
        dstPath += QDir::separator();

    bool error = false;
    QStringList fileNames = directory.entryList(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden);
    for (QStringList::size_type i=0; i != fileNames.size(); ++i)
    {
        QString fileName = fileNames.at(i);
        QString srcFilePath = srcPath + fileName;
        QString dstFilePath = dstPath + fileName;
        QFileInfo fileInfo(srcFilePath);
        if (fileInfo.isFile() || fileInfo.isSymLink())
        {
            if (override)
            {
                QFile::setPermissions(dstFilePath, QFile::WriteOwner);
            }
            QFile::copy(srcFilePath, dstFilePath);
        }
        else if (fileInfo.isDir())
        {
            QDir dstDir(dstFilePath);
            dstDir.mkpath(dstFilePath);
            if (!CopyFolder(
                        dstFilePath.toLatin1().data(),
                        srcFilePath.toLatin1().data(),
                        override))
            {
                error = true;
            }
        }
    }
    return !error;
}
//打印长度控制 1 ok -1 faild 2 succ some
int CLComFuncs::SprintfSafe(char* outBuffer, quint64 nSize, vector<_tagARGNode>& vec)
{
    if (!outBuffer || nSize == 0)
    {
        return -1;
    }
    size_t nTempSize = 0;
    for (size_t i = 0; i < vec.size(); ++i)
    {
        if (vec[i].pValue)
        {
            switch (vec[i].aType)
            {
            case E_ARG_TYPE_NO:
                break;
            case E_ARG_TYPE_SHORT:
            case E_ARG_TYPE_INT:
            case E_ARG_TYPE_LONG:
            {
                                    int nValue = *((int*)vec[i].pValue);
                                    char buffer[64] = { 0 };
                                    sprintf(buffer, "%d", nValue);

                                    size_t ncsize = strlen(buffer);
                                    if (nTempSize + ncsize > nSize)
                                    {
                                        if (nTempSize > 0)
                                        {
                                            return 2;
                                        }
                                        return -1;
                                    }
                                    strncat(outBuffer + nTempSize, buffer, ncsize);
                                    nTempSize += ncsize;
            }
                break;
            case E_ARG_TYPE_LONGLONG:
            {
                                        quint64 nValue = *((quint64*)vec[i].pValue);
                                        char buffer[64] = { 0 };
                                        sprintf(buffer, "%lld", nValue);
                                        int ncsize = (int)strlen(buffer);
                                        if (nTempSize + ncsize > nSize)
                                        {
                                            if (nTempSize > 0)
                                            {
                                                return 2;
                                            }
                                            return -1;
                                        }
                                        strncat(outBuffer + nTempSize, buffer, ncsize);
                                        nTempSize += ncsize;
            }
                break;
            case E_ARG_TYPE_FLOAT:
            case E_ARG_TYPE_DOUBLE:
            {
                                      double dValue = *((double*)vec[i].pValue);
                                      char buffer[256] = { 0 };
                                      sprintf(buffer, "%0.6f", dValue);

                                      int ncsize = (int)strlen(buffer);
                                      if (nTempSize + ncsize > nSize)
                                      {
                                          if (nTempSize > 0)
                                          {
                                              return 2;
                                          }
                                          return -1;
                                      }
                                      strncat(outBuffer + nTempSize, buffer, ncsize);
                                      nTempSize += ncsize;
            }
                break;
            case E_ARG_TYPE_CHARS:
            {
                                     string tempstr = (char*)vec[i].pValue;
                                     if ((nTempSize + tempstr.length()) > nSize)
                                     {
                                         if (nTempSize > 0)
                                         {
                                             return 2;
                                         }
                                         return -1;
                                     }
                                     else
                                     {
                                         strncat(outBuffer + nTempSize, tempstr.c_str(), tempstr.length());
                                     }
                                     nTempSize += (int)tempstr.length();
            }
                break;
            default:
                break;
            }
        }
    }

    return 1;
}
string CLComFuncs::FormatString(int nMaxSize, const char* szFormat, ...)
{
    if (nMaxSize >= 1024)
    {
        return "";
    }
    char czBuffer[1024] = { 0 };

    va_list vl;
    va_start(vl, szFormat);
#ifdef Q_OS_WINDOW
    _vsnprintf(czBuffer, 1024 - 1, szFormat, vl);
#endif
#ifdef Q_OS_LINUX
    vsnprintf(czBuffer, 1024 - 1, szFormat, vl);
#endif
    va_end(vl);

    return czBuffer;
}
void CLComFuncs::SearchFiles(string path, bool bfindDir, vector<string>& vec)
{
    string findfilename = path;
    findfilename += "\\*.*";

    QDir dir(path.c_str());
    if(!dir.exists())
    {
        return;
    }
    dir.setFilter(QDir::Files | QDir::NoSymLinks);
    QFileInfoList list = dir.entryInfoList();

    int file_count = list.count();
    if(file_count <= 0)
    {
        return;
    }

    QStringList string_list;
    for(int i=0; i<file_count; i++)
    {
        QFileInfo file_info = list.at(i);
        QString suffixf = file_info.suffix();

        if(file_info.isDir() && suffixf.length() == 0)
        {
            if (bfindDir)
            {
                SearchFiles(file_info.path().toLatin1().data(), bfindDir, vec);
            }
        }
        else
        {
            vec.push_back(file_info.absolutePath().toLatin1().data());
        }
    }
}
